#pragma once

#include <stdint.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

#include "default_handler.h"
#include "MemoryPool.h"

using boost::asio::ip::tcp;

template <class Session, uint16_t Port, class init_functor > class Server
{
	public:
		Server( boost::asio::io_service &io, init_functor init_function  ) : io_s( io ), _acceptor( io, tcp::endpoint( tcp::v4(), Port  ) )
		{
			try
			{
				Session *s = new Session( &io_s );

				if( s != 0 )
				{
					_acceptor.async_accept( s->socket(), boost::bind( &Server::handle_accept, this, s, boost::asio::placeholders::error ) );
				}
			}
			catch( std::exception &e )
			{
				printf( "Deleted the pool\n" );
				delete this;
			}
		}

		~Server()
		{
			printf( "Quiting for some reason\n" );
		}
		
		void handle_accept( Session *s, const boost::system::error_code &error )
		{
			try
			{
				if( !error )
				{
					s->start();

					s = new Session( &io_s );

					if( s != 0 )
					{
						//s->setPool( pool );
					
						_acceptor.async_accept( s->socket(), boost::bind( &Server::handle_accept, this, s, boost::asio::placeholders::error ) );
					}
					else
					{
						s->socket().close();
					}
				}
				else
				{
					delete s;
				}
			}
			catch( std::exception &e )
			{
				delete this;
			}
		}

	private:
		boost::asio::io_service &io_s;
		tcp::acceptor _acceptor;
}; 

